import datetime
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn import metrics, tree
from sklearn.preprocessing import Binarizer


def train_model(x_train, y_train, model=None):
    #
    # ---认识学习曲线，不用自己分组---
    # vs.ModelLearning(dfFeatures, dfY)

    # ---认识 Bias vs Variance---
    # 在函数内部有分组，不用自己分组
    # vs.ModelComplexity(dfFeatures, dfY)

    # Fit the training data to the model using grid search
    # reg = fit_model(x_train, y_train)

    # Produce the value for 'max_depth'
    # print("Parameter 'max_depth' is {} for the optimal model.".format(reg.get_params()['max_depth']))

    # ---Model---
    if model == None:
        regressor = LogisticRegression(solver='lbfgs',
                                       multi_class='ovr')  # multi_class='multinomial'
    else:
        regressor = model
    #
    regressor.fit(x_train, y_train)
    #
    return regressor


# 混淆矩阵
def performance_metric(y_true, y_pred):

    acc = metrics.accuracy_score(y_true, y_pred)
    # accuracy_score(y_true, y_pred, normalize=False) # 类似海明距离，每个类别求准确后，再求微平均

    precision = metrics.precision_score(y_true, y_pred)
    a1 = metrics.precision_score(y_true, y_pred, average='micro')  # 微平均，精确率
    a2 = metrics.precision_score(y_true, y_pred, average='macro')  # 宏平均，精确率
    recall = metrics.recall_score(y_true, y_pred)
    f1 = metrics.f1_score(y_true, y_pred)

    #
    print("Acc", acc, "Precision", precision, "Recall", recall, "F1", f1)


#
def train(df_x, df_y, model=None):

    # ---拆分数据集---
    # x_train, x_test, y_train, y_test = train_test_split(dfFeatures, dfY, test_size=0.2, random_state=1)
    x_train = df_x
    y_train = df_y

    # ---Build Model---
    regressor = train_model(x_train, y_train, model)

    # ---Test---
    y_predicted = regressor.predict(x_train)

    # score = Performance_Metric(y_test, y_predicted)
    performance_metric(y_train, y_predicted)
    #
    return regressor


if __name__ == '__main__':
    # 读取数据
    df_data = pd.read_csv('e:\\FCST_HS300.csv')
    # df_data = df_data[:20]

    # 预处理数据
    df_data = df_data.drop(df_data.columns[[0]], axis=1)

    # 准备 Y
    # x y 时间本是一一对应，实际上x 应该对应 next y
    df_data["Z_HS300_Next"] = df_data["Z_HS300"].shift(-1)  # 构建错位项
    # 因为错位最后一行会形成空数据， drop掉
    df_data.dropna(subset=["Z_HS300_Next"], inplace=True)
    print(df_data)
    # 取出Y
    df_y = df_data[["Z_HS300_Next"]]

    # 把 Y 变成枚举变量（0 1），用于分类， 0 1 代表涨跌（真实操作中一般不会以0为界）
    bn = Binarizer(threshold=0)
    bin_y = bn.fit_transform(df_y)
    bin_y = bin_y.ravel()

    print(bin_y)

    df_x = df_data.drop(columns=["Z_HS300", "Z_HS300_Next"])
    # df_x = df_data.drop(columns=["Z_HS300"])

    #
    train(df_x, bin_y)